package org.xiezc.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xiezc.InitializeListerner;
import org.xiezc.aes.AesException;
import org.xiezc.aes.WXBizMsgCrypt;
import org.xml.sax.InputSource;

/**
 * 
 * @author xiezc
 *
 */
public class RequestUtil {
	private static Logger logger=Logger.getLogger(RequestUtil.class);
	
	private WXBizMsgCrypt wXBizMsgCrypt = InitializeListerner.wXBizMsgCrypt;
	private Map<String, String> parmsMap;

	private RequestUtil(Map<String, String> map) {
		this.parmsMap = map;
	}

	/**
	 * 获得解析消息，将消息放入的Map
	 * 
	 * @return
	 */
	public Map<String, String> getReqMap() {
		String postData = this.getPostData();
		Map<String, String> map = new HashMap<>();
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			StringReader sr = new StringReader(postData);
			InputSource is = new InputSource(sr);
			logger.info("接受到的消息是："+postData);
			Document document = db.parse(is);
			// 获得根目录
			Element root = document.getDocumentElement();
			// 获得子目录
			NodeList nodeList = root.getChildNodes();
			for (int i = 0; i < nodeList.getLength(); i++) {
				String nodeName = nodeList.item(i).getNodeName();
				String nodeText = nodeList.item(i).getTextContent();
				map.put(nodeName, nodeText);
			}
			logger.info("解析出的map是："+map);
			return map;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 获得实体类，此实体类中包含微信请求的参数
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	public static RequestUtil getInstance(HttpServletRequest request) throws IOException {
		Enumeration<String> parmName = request.getParameterNames();
		Map<String, String> parmsMap = new HashMap<>();
		while (parmName.hasMoreElements()) {
			String string = (String) parmName.nextElement();
			String value = request.getParameter(string);
			parmsMap.put(string, value);
		}
		BufferedReader bufferedReader =new BufferedReader( new InputStreamReader(request.getInputStream(),"utf-8"));
		StringBuffer sb = new StringBuffer();
		String line;
		while ((line = bufferedReader.readLine()) !=null) {
			sb.append(line);
		}
		parmsMap.put("content", sb.toString().trim());
		return new RequestUtil(parmsMap);
	}

	/**
	 * 如果启动了加密模式，则有此参数
	 * 
	 * @return 加密类型，为aes
	 */
	public String getEncrypt_type() {
		return parmsMap.get("encrypt_type");
	}

	/**
	 * 如果启动了加密模式，则有此参数，
	 * 
	 * @return 消息体签名，用于验证消息体的正确性
	 */
	public String getMsg_signature() {
		return parmsMap.get("msg_signature");
	}

	/**
	 * 获得消息体.如果消息加了密，则解密消息后返回明文，未加密则直接返回明文
	 * 
	 * @param requestUtil
	 * @return
	 */
	public String getPostData() {
		try {
			String encrypt_type = this.getEncrypt_type();
			if ("aes".equals(encrypt_type)) {
				String content = wXBizMsgCrypt.decryptMsg(this.getMsg_signature(), this.getTimestamp(), this.getNonce(),
						parmsMap.get("content"));
				parmsMap.put("content", content);
				return content;
			} else {
				return parmsMap.get("content");
			}
		} catch (AesException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @return 时间戳
	 */
	public String getTimestamp() {
		return parmsMap.get("timestamp");
	}

	/**
	 * 消息体等加密的随机串（加密算法的‘盐’）
	 * 
	 * @return
	 */
	public String getNonce() {
		return parmsMap.get("nonce");
	}

	/**
	 * 微信服务器发送的随机字符串，此字符串是经过加密的
	 * 
	 * @return
	 */
	public String getEchostr() {
		return parmsMap.get("echostr");
	}

}
